import { Controller, Get, HttpStatus, Logger } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { DatabaseService } from '../services/database.service';
import { HeliusService } from '../services/helius.service';
import { RealtimeGateway } from '../gateways/realtime.gateway';

@ApiTags('health')
@Controller('api/health')
export class HealthController {
  private readonly logger = new Logger(HealthController.name);

  constructor(
    private readonly database: DatabaseService,
    private readonly heliusService: HeliusService,
    private readonly realtimeGateway: RealtimeGateway,
  ) {}

  @Get()
  @ApiOperation({ summary: 'Basic health check' })
  @ApiResponse({ status: 200, description: 'Service is healthy' })
  async getHealth() {
    return {
      status: 'ok',
      timestamp: new Date().toISOString(),
      uptime: process.uptime(),
      version: process.env.npm_package_version || '1.0.0',
    };
  }

  @Get('detailed')
  @ApiOperation({ summary: 'Detailed health check with dependencies' })
  @ApiResponse({ status: 200, description: 'Detailed health status' })
  async getDetailedHealth() {
    const checks = {
      database: false,
      helius: false,
      websocket: false,
    };

    const startTime = Date.now();

    try {
      // 检查数据库连接
      checks.database = await this.database.healthCheck();
    } catch (error) {
      this.logger.error('Database health check failed:', error);
    }

    try {
      // 检查 Helius 连接
      const connection = await this.heliusService.getConnection();
      const version = await connection.getVersion();
      checks.helius = !!version;
    } catch (error) {
      this.logger.error('Helius health check failed:', error);
    }

    try {
      // 检查 WebSocket 连接
      checks.websocket = this.realtimeGateway.getOnlineUsersCount() >= 0;
    } catch (error) {
      this.logger.error('WebSocket health check failed:', error);
    }

    const responseTime = Date.now() - startTime;
    const allHealthy = Object.values(checks).every(check => check);

    return {
      status: allHealthy ? 'ok' : 'partial',
      timestamp: new Date().toISOString(),
      uptime: process.uptime(),
      responseTime: `${responseTime}ms`,
      version: process.env.npm_package_version || '1.0.0',
      checks,
      websocket: {
        onlineUsers: this.realtimeGateway.getOnlineUsersCount(),
      },
    };
  }

  @Get('ready')
  @ApiOperation({ summary: 'Readiness probe for Kubernetes' })
  @ApiResponse({ status: 200, description: 'Service is ready' })
  @ApiResponse({ status: 503, description: 'Service is not ready' })
  async getReadiness() {
    try {
      const isDatabaseReady = await this.database.healthCheck();
      
      if (!isDatabaseReady) {
        return {
          status: 'not ready',
          reason: 'Database not accessible',
          timestamp: new Date().toISOString(),
        };
      }

      return {
        status: 'ready',
        timestamp: new Date().toISOString(),
      };
    } catch (error) {
      this.logger.error('Readiness check failed:', error);
      throw error;
    }
  }

  @Get('live')
  @ApiOperation({ summary: 'Liveness probe for Kubernetes' })
  @ApiResponse({ status: 200, description: 'Service is alive' })
  async getLiveness() {
    return {
      status: 'alive',
      timestamp: new Date().toISOString(),
      uptime: process.uptime(),
      memory: process.memoryUsage(),
    };
  }
}
